﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace SkinableFormsLib
{
	public class Utils
	{
		public static void BitmapMakeTransparent(ref Bitmap bitmap, ref Rectangle bounds, ref byte bc, ref byte gc, ref byte rc)
		{
			BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
			for (int i = 0; i < bd.Height * bd.Width * 4; i += 4)
			{
				if (Marshal.ReadByte(bd.Scan0, i + 3) > 0 && Marshal.ReadByte(bd.Scan0, i) == bc && Marshal.ReadByte(bd.Scan0, i + 1) == gc && Marshal.ReadByte(bd.Scan0, i + 2) == rc)
					Marshal.WriteByte(bd.Scan0, i + 3, 0);

			}

			bitmap.UnlockBits(bd);

		}



		public static void BitmapMakeTransparentUnsafe(ref Bitmap bitmap, ref Rectangle bounds, ref byte bc, ref byte gc, ref byte rc)
		{
			BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
			unsafe
			{
				for (int i = 0; i < bd.Height * bd.Width * 4; i += 4)
				{
					byte* row = (byte*)bd.Scan0 + i;
					//if alpha not zero and channels match backcolor set alpha to 0
					//bitblt and such failed
					int dd = 2;
					if (row[3] >= 0)
					{
						if (-dd < (row[0] - bc) && (row[0] - bc) < dd)
						{
							if (-dd < (row[1] - gc) && (row[1] - gc) < dd)
							{
								if (-dd < (row[2] - rc) && (row[2] - rc) < dd)
								{
									row[3] = 0;
								}
							}
						}

					}

					//if (row[3] > 0 && row[0] == bc && row[1] == gc && row[2] == rc)                        row[3] = 0;

				}
			}
			bitmap.UnlockBits(bd);

		}



		public static void BitmapSetOpacity(ref Bitmap bitmap, ref Rectangle bounds, ref byte _opacity)
		{
			BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
			for (int i = 0; i < bd.Height * bd.Width * 4; i += 4)
			{

				Marshal.WriteByte(bd.Scan0, i + 3, _opacity);

			}

			bitmap.UnlockBits(bd);

		}

		public static void BitmapSetChannelValue(ref Bitmap bitmap, ref Rectangle bounds, int _channel, byte _value)
		{
			if (_channel < 0 || _channel > 3)
				return;
			BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
			IntPtr sc0 = bd.Scan0;
			for (int i = 0; i < bd.Height * bd.Width * 4; i += 4)
			{

				if (Marshal.ReadByte(sc0, i + 3) > 0)
					Marshal.WriteByte(sc0, i + _channel, _value);

			}
			bitmap.UnlockBits(bd);
		}

		public static void BitmapSetChannelsValue(ref Bitmap bitmap, ref Rectangle bounds, ref byte _red, ref byte _green, ref byte _blue)
		{
			BitmapData bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
			IntPtr sc0 = bd.Scan0;
			for (int i = 0; i < bd.Height * bd.Width * 4; i += 4)
			{

				if (Marshal.ReadByte(sc0, i + 3) > 0)
				{
					Marshal.WriteByte(sc0, i, _blue);
					Marshal.WriteByte(sc0, i + 1, _green);
					Marshal.WriteByte(sc0, i + 2, _red);
				}

			}

			bitmap.UnlockBits(bd);

		}



		public static void TextBoxAdjustShadowRectangle(IntPtr handle, ref Rectangle _shadowRect)
		{
			int style = Win32.GetWindowLong(handle, Win32.GWL_STYLE);
			if (((style & Win32.WS_HSCROLL) != 0))
			{
				_shadowRect.Height -= System.Windows.Forms.SystemInformation.HorizontalScrollBarHeight;
			}
			if (((style & Win32.WS_VSCROLL) != 0))
			{
				_shadowRect.Width -= System.Windows.Forms.SystemInformation.VerticalScrollBarWidth;
			}
		}



		public static int MAKELONG(int low, int high)
		{
			return (high << 16) | (low & 0xffff);
		}

		public static IntPtr MAKELPARAM(int low, int high)
		{
			return (IntPtr)((high << 16) | (low & 0xffff));
		}

		public static int HIWORD(int n)
		{
			return (n >> 16) & 0xffff;
		}

		public static int HIWORD(IntPtr n)
		{
			return HIWORD(unchecked((int)(long)n));
		}

		public static int LOWORD(int n)
		{
			return n & 0xffff;
		}

		public static int LOWORD(IntPtr n)
		{
			return LOWORD(unchecked((int)(long)n));
		}

		public static int SignedHIWORD(IntPtr n)
		{
			return SignedHIWORD(unchecked((int)(long)n));
		}
		public static int SignedLOWORD(IntPtr n)
		{
			return SignedLOWORD(unchecked((int)(long)n));
		}

		public static int SignedHIWORD(int n)
		{
			int i = (int)(short)((n >> 16) & 0xffff);

			return i;
		}

		public static int SignedLOWORD(int n)
		{
			int i = (int)(short)(n & 0xFFFF);

			return i;
		}



		/// <summary>
		/// Returns current transparency flag relative to cleartype
		/// </summary>
		/// <param name="c"></param>
		/// <returns></returns>
		public static bool GetTransparency(Control c)
		{

			if (!(c is ILWControl))
			{
				//Console.WriteLine("NOT ILWControl");
				return false;
			}
			ILWControl ilwc = (ILWControl)c;
			bool ret = false;

			if (Win32.SmoothingModeIsClearType())
			{
				ret = false;
				if (c.BackColor != ilwc.LWDesiredBackColor)
				{
					c.BackColor = ilwc.LWDesiredBackColor;
				}
			}
			else
			{

				if (ilwc.LWTransparent /*&& !ilwc.LWTransparency*/)
				{
					ret = true;
					if (c.BackColor != ilwc.LWTransparentColor)
					{
						c.BackColor = ilwc.LWTransparentColor;
					}
				}
			}

			return ret;
		}




		public enum ProgressBarOrientation : int
		{
			Horizontal = 0,
			Vertical = 1
		}





	}

}
